﻿using System;
using System.Collections;
using System.Security.Cryptography;
using System.Web.Security;
using ChapterX.Common;
using ChapterX.Data;
using ChapterX.Data.UsersDSTableAdapters;
using ChapterX.Data.BooksDSTableAdapters;

namespace ChapterX.BusinessFacade
{
    public class UserSystem
    {
        public const String ROLE_LIBRARIAN = "Librarian";
        public const String ROLE_TEACHER = "Teacher";
        public const String ROLE_STUDENT = "Student";

        public UsersDS.UsersRow GetUserByUsername(String username)
        {
            UsersTableAdapter adapter = new UsersTableAdapter();
            UsersDS.UsersDataTable table = adapter.GetUserByUsername(username);

            if (null != table && table.Rows.Count > 0)
            {
                return table[0];
            }
            else
            {
                return null;
            }
        }

        public void UserLogin(String userName, String ip)
        {
            try
            {
                using (UsersTableAdapter adapter = new UsersTableAdapter())
                {
                    adapter.UserLogin(userName, ip);
                }
            }
            catch
            {
            }
        }

        //public bool CreateUser(String userName, String password, String roles, int centerId,
        //    String email, String realName, String phoneNumber, String address, String zipCode,
        //    String qmd, bool isActivated)
        //{
        //    if (!CurrentUserInfo.IsAdmin)
        //    {
        //        throw new UnauthorizedException();
        //    }

        //    if (Exists(userName))
        //    {
        //        throw new RecordAlreadyExistedException("指定的用户已存在。");
        //    }
        //    else
        //    {
        //        String passwordSalt = CreateSalt(ForeignConfiguration.PasswordSaltSize);
        //        String passwordHash = CreatePasswordHash(password, passwordSalt);

        //        UsersTableAdapter adapter = new UsersTableAdapter();
        //        int result = adapter.Insert(
        //            userName, passwordHash, passwordSalt, roles, centerId, email,
        //            realName, phoneNumber, address, zipCode, qmd, null, null, DateTime.Now,
        //            isActivated);

        //        return (result == 1);
        //    }
        //}

        public bool UpdateUser(String userName, String password, String roles, int centerId,
            String email, String realName, String phoneNumber, String address, String zipCode,
            String qmd, bool isActivated)
        {
            if (!CurrentUserInfo.IsLibrarian && !userName.Equals(CurrentUserInfo.Username))
            {
                throw new UnauthorizedException();
            }

            UsersDS.UsersRow user = GetUserByUsername(userName);

            if (null == user)
            {
                throw new RecordNotExistedException("指定的用户不存在。");
            }
            else
            {
                if (Utils.HasValue(password))
                {
                    String passwordSalt = CreateSalt(ChapterXConfiguration.PasswordSaltSize);
                    String passwordHash = CreatePasswordHash(password, passwordSalt);
                    user.PasswordHash = passwordHash;
                    user.PasswordSalt = passwordSalt;
                }
                user.Roles = roles;
                user.RealName = realName;
                
                UsersTableAdapter adapter = new UsersTableAdapter();
                int result = adapter.Update(user);

                return (result == 1);
            }
        }

        public bool Exists(String username)
        {
            return (null != GetUserByUsername(username));
        }

        public bool IsTeacher(String username)
        {
            return GetUserRoles(username).Contains(ROLE_TEACHER);
        }

        public bool VerifyPassword(String userName, String suppliedPassword)
        {
            if (!Exists(userName))
            {
                throw new RecordNotExistedException("指定的用户不存在。");
            }
            else
            {
                UsersDS.UsersDataTable table = (new UsersTableAdapter()).GetUserByUsername(userName);
                UsersDS.UsersRow dbUser = table[0];
                String dbPasswordSalt = dbUser.PasswordSalt;
                String dbPasswordHash = dbUser.PasswordHash;
                String passwordHash = CreatePasswordHash(suppliedPassword, dbPasswordSalt);

                return passwordHash.Equals(dbPasswordHash);

            }
        }

        //public bool ResetPassword(String userName, String newPassword)
        //{
        //    if (!IsUserExisted(userName))
        //    {
        //        throw new RecordNotExistedException("指定的用户不存在。");
        //    }
        //    else
        //    {
        //        String newPasswordSalt = CreateSalt(ForeignConfiguration.PasswordSaltSize);
        //        String newPasswordHash = CreatePasswordHash(newPassword, newPasswordSalt);

        //        Users.UsersRow user = GetUserByUserName(userName);
        //        user.PasswordHash = newPasswordHash;
        //        user.PasswordSalt = newPasswordSalt;

        //        return UpdateUser(user);
        //    }
        //}

        //public bool ActivateUser(String userName)
        //{
        //    bool isUserExisted, isUserActivated;
        //    CheckUser(userName, out isUserExisted, out isUserActivated);

        //    if (isUserActivated)
        //    {
        //        return true;
        //    }
        //    else if (!isUserExisted)
        //    {
        //        throw new RecordNotExistedException("指定的用户不存在。");
        //    }
        //    else
        //    {
        //        Users.UsersRow user = GetUserByUserName(userName);
        //        user.IsActivated = true;

        //        return UpdateUser(user);
        //    }
        //}

        //public bool DeactivateUser(String userName)
        //{
        //    bool isUserExisted, isUserActivated;
        //    CheckUser(userName, out isUserExisted, out isUserActivated);

        //    if (!isUserActivated)
        //    {
        //        return true;
        //    }
        //    else if (!isUserExisted)
        //    {
        //        throw new RecordNotExistedException("指定的用户不存在。");
        //    }
        //    else
        //    {
        //        Users.UsersRow user = GetUserByUserName(userName);
        //        user.IsActivated = false;

        //        return UpdateUser(user);
        //    }
        //}

        public String GetUserRoles(String userName)
        {
            UsersDS.UsersRow user = GetUserByUsername(userName);
            if (null != user)
            {
                ArrayList roles = new ArrayList();

                // Fetch
                if (Utils.HasValue(user.Roles))
                {
                    foreach (String role in user.Roles.Split(
                        (new char[] { '|', ',' }), StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (!roles.Contains(role.Trim()))
                        {
                            roles.Add(role.Trim());
                        }
                    }
                }

                return String.Join("|", (String[])(roles.ToArray(typeof(String))));
            }
            else
            {
                return String.Empty;
            }
        }

        //public Users.UsersOutlineDataTable GetUsersOutline()
        //{
        //    UsersOutlineTableAdapter adapter = new UsersOutlineTableAdapter();
        //    Users.UsersOutlineDataTable table = adapter.GetData();

        //    return table;
        //}

        protected String CreateSalt(int size)
        {
            // Generate a cryptographic random number using the cryptographic
            // service provider
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[size];
            rng.GetBytes(buff);
            // Return a Base64 string representation of the random number
            return Convert.ToBase64String(buff);
        }

        protected String CreatePasswordHash(String pwd, String salt)
        {
            String saltAndPwd = String.Concat(pwd, salt);
            String hashedPwd =
                FormsAuthentication.HashPasswordForStoringInConfigFile(
                saltAndPwd, "SHA1");
            return hashedPwd;
        }
    }
}

